<?php

namespace hamster\tools\com;

// 文件上传类
class Hupload
{
    public $error;
    public $path; // 文件保存路径
    public $url; // 文件访问地址
    public $name; // 文件名称
    public $imageInfo=[]; // 图片信息

	// $_FILES错误码信息
    protected static $errorCont = [
        '0' => '正常，上传成功。',
        '1' => '超过php.ini允许的大小。',
        '2' => '超过表单允许的大小。',
        '3' => '图片只有部分被上传。',
        '4' => '请选择图片。',
        '6' => '找不到临时目录。',
        '7' => '写文件到硬盘出错。',
        '8' => 'php文件上传扩展没有打开。',
    ];
    // 支持上传的文件类型
    protected static $typeCont = [
        'image/jpeg' => 'jpg',
        'image/pjpeg' => 'jpg',
        'image/png' => 'png',
        'image/gif' => 'gif',
    ];
    // getimagesize获取的图片渠道
    protected static $imageChannel = [
		 1 => 'GIF',
		 2 => 'JPG',
		 3 => 'PNG',
		 4 => 'SWF',
		 5 => 'PSD',
		 6 => 'BMP',
		 7 => 'TIFF(intel byte order)',
		 8 => 'TIFF(motorola byte order)',
		 9 => 'JPC',
		 10 => 'JP2',
		 11 => 'JPX',
		 12 => 'JB2',
		 13 => 'SWC',
		 14 => 'IFF',
		 15 => 'WBMP',
		 16 => 'XBM'
	];

	/**
	 * Upload constructor.
	 * @param array $typeCont 指定允许上传的格式
	 */
    public function __construct($typeCont=[])
    {
		if (!empty($typeCont)) {
			self::$typeCont = $typeCont;
		}
    }

    /**
     * @desc 获取错误信息
     * @return mixed
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * @desc 获取上传文件的路径
     * @return string
     */
    public function getUrl()
    {
        return $this->url;
    }

    /**
     * @desc 获取上传图片的信息
     * @return array
     */
    public function getImageInfo()
    {
        return $this->imageInfo;
    }


    /**
     * @desc 过滤错误信息并返回文件类型
     * @param array $fileData 文件信息
     * @return bool|mixed
     */
    protected function _filter($fileData)
    {
        if (!$fileData)
        {
            $this->error = '上传文件不能为空';
            return false;
        }

        // 返回错误信息
        if ($fileData['error'] > 0)
        {
            if (!empty(self::$errorCont[$fileData['error']]))
            {
                $this->error = self::$errorCont[$fileData['error']];
            } else {
                $this->error = '未知错误。';
            }
            return false;
        }

        // 获取类型
        if (!empty(self::$typeCont[$fileData['type']]))
        {
            $picTypeRet = self::$typeCont[$fileData['type']];
        } else {
            $this->error = '文件类型不支持';
            return false;
        }

        return $picTypeRet;
    }


    /**
     * @desc 本地图片上传
	 * @param array $fileData $_FILES获取的数据（eg:Array ( [name] => 001.jpg [type] => image/jpeg [tmp_name] => C:\Windows\Temp\php49FD.tmp [error] => 0 [size] => 239550 )）
	 * @param string $savePath 保存目录
     * @return bool|mixed
     */
    public function imageSave($fileData, $savePath)
    {
        // 过滤错误信息并返回文件类型
        $picTypeRet = $this->_filter($fileData);
        if (!$picTypeRet) {
        	return $picTypeRet;
		}

        // 没有目录则创建
        if(!is_dir($savePath))
        {
            mkdir($savePath,0777, true);
        }

        // 生成新的文件名称
        $newPicName = md5(uniqid());
        $newPicPah = $savePath . '/' . $newPicName . "." . $picTypeRet;
        $result = move_uploaded_file($fileData["tmp_name"], $newPicPah); // 转移到指定目录

        if (!$result) {
            $this->error = '图片保存失败';
            return false;
        }

        // 检查图片是否已经存在
        try {
            $image = self::imageOpen($newPicPah);
            if (empty($image))
            {
                $this->error = '图片信息获取异常';
                return false;
            } else {
            	$this->imageInfo = [
            		'width' => $image[0],
            		'height' => $image[1],
            		'channel' => self::$imageChannel[$image[2]],
            		'mime' => $image['mime'],
				];
			}
        } catch(\Exception $e) {
            $this->error = '图片信息获取失败';
            return false;
        }


        $this->name = $newPicName . "." . $picTypeRet;
        $this->path = $savePath;
        $this->url = $newPicPah;

        return $this;
    }

	/**
	 * 获取图片信息
	 * @param string $file 保存后的图片路径
	 * @return array|bool|false
	 */
	public static function imageOpen($file)
	{
		if (is_string($file)) {
			$file = new \SplFileInfo($file);
		}
		if (!$file->isFile()) {
			return false;
		}

		$info = @getimagesize($file->getPathname());
		return $info;
	}

	/**
	 * 本地文件上传
	 * @param array $fileData $_FILES获取的数据（eg:Array ( [name] => 001.jpg [type] => image/jpeg [tmp_name] => C:\Windows\Temp\php49FD.tmp [error] => 0 [size] => 239550 )）
	 * @param string $savePath 保存目录
	 * @param bool $reservedName 是否使用原来文件名保存
	 * @return $this|bool
	 */
    public function fileSave($fileData, $savePath, $reservedName=false)
    {
		// 过滤错误信息并返回文件类型
		$picTypeRet = $this->_filter($fileData);
		if (!$picTypeRet) {
			return $picTypeRet;
		}

		if (!is_dir($savePath)) {
			// 创建不存在的目录
			mkdir($savePath, 0777, true);
		}

        if ($reservedName) {
            // 保留原来的文件名称
            $newName = $fileData['name'];
        } else {
            // 生成新的文件名称
            $newName = md5(uniqid());
            $picTypeRet = explode('.', $fileData['name'])[1];
            $newName = $newName . "." . $picTypeRet;
        }

        $newPah = $savePath . '/' . $newName;
        $result = move_uploaded_file($fileData["tmp_name"], $newPah); // 转移到指定目录


        if (!$result) {
            $this->error = '文件保存失败';
            return false;
        }

        $this->name = $newName;
        $this->path = $savePath ;
        $this->url = $savePath . '/' . $newName;

        return $this;
    }


}